// Response.h
//
// A response from one part of the system to another.
//

#ifndef __RESPONSE_H__
#define __RESPONSE_H__

#include "base/Packet.h"
#include "base/Request.h"
#include "util/Pool.h"

typedef enum {
    RESPONSE_DONE,
    RESPONSE_NACK_RETRY,
    RESPONSE_NACK_ABORT,
    RESPONSE_NACK_BLOCK,
    RESPONSE_NACK_CONFLICT,
    RESPONSE_NACK_SNAPSHOT_DATA,
    RESPONSE_SNOOP_RESPONSE,
    RESPONSE_NO_SNOOP_RESPONSE,
} ResponseFlag;

class Response : public Packet {
  public:
    NEW_DELETE_OPERATORS_H(Response,Packet);

    Response(Request* req, ResponseFlag _flag, uint size) :
        Packet(req->getDestination(), req->getSource(), size),
        request(req),
        nacked(false),
        flag(_flag)
        { }
        
    Response(Request* req, uint size) :
        Packet(req->getDestination(), req->getSource(), size),
        request(req),
        nacked(false),
        flag(RESPONSE_DONE)
        { }

    Response(Request* req) :
        Packet(req->getDestination(), req->getSource(), req->getSize()),
        request(req),
        nacked(false),
        flag(RESPONSE_DONE)       
        { }

    virtual ~Response() {}

    Request* getRequest() const { return request; }
    void setRequest(Request* r) { request = r; }

    ResponseFlag getFlag() const {
        return flag;
    }

    void setFlag(ResponseFlag _flag) {
        flag = _flag;
    }

    static bool isNack(ResponseFlag _flag) {
        return (_flag == RESPONSE_NACK_ABORT ||
                _flag == RESPONSE_NACK_BLOCK ||
                _flag == RESPONSE_NACK_RETRY ||
                _flag == RESPONSE_NACK_CONFLICT ||
                _flag == RESPONSE_NACK_SNAPSHOT_DATA);
    }
    
    virtual char const* toString() const;
    
  protected:
    Request* request;
    bool nacked;
    ResponseFlag flag;
};

#endif // __RESPONSE_H__

